package service

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/google/uuid"
	"go.uber.org/zap"

	"yanxue_ai_go/pkg/common/database"
	"yanxue_ai_go/pkg/common/logger"
	"yanxue_ai_go/services/agent/internal/models"
)

type AgentService struct{}

func NewAgentService() *AgentService {
	return &AgentService{}
}

// CreateAgent 创建代理
func (s *AgentService) CreateAgent(ctx context.Context, req *CreateAgentRequest) (*models.Agent, error) {
	agent := &models.Agent{
		Name:        req.Name,
		Description: req.Description,
		Type:        req.Type,
		Config:      req.Config,
		Model:       req.Model,
		Version:     req.Version,
		CreatedBy:   req.CreatedBy,
		Status:      "inactive",
	}

	if err := database.DB.Create(agent).Error; err != nil {
		logger.Logger.Error("Failed to create agent", zap.Error(err))
		return nil, fmt.Errorf("failed to create agent: %w", err)
	}

	logger.Logger.Info("Agent created successfully", zap.Uint("agent_id", agent.ID))
	return agent, nil
}

// GetAgent 获取代理
func (s *AgentService) GetAgent(ctx context.Context, id uint) (*models.Agent, error) {
	var agent models.Agent
	if err := database.DB.Preload("Tasks").Preload("Executions").First(&agent, id).Error; err != nil {
		return nil, fmt.Errorf("agent not found: %w", err)
	}
	return &agent, nil
}

// ListAgents 获取代理列表
func (s *AgentService) ListAgents(ctx context.Context, req *ListAgentsRequest) ([]*models.Agent, int64, error) {
	var agents []*models.Agent
	var total int64

	query := database.DB.Model(&models.Agent{})

	if req.Type != "" {
		query = query.Where("type = ?", req.Type)
	}
	if req.Status != "" {
		query = query.Where("status = ?", req.Status)
	}

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("failed to count agents: %w", err)
	}

	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Find(&agents).Error; err != nil {
		return nil, 0, fmt.Errorf("failed to list agents: %w", err)
	}

	return agents, total, nil
}

// UpdateAgent 更新代理
func (s *AgentService) UpdateAgent(ctx context.Context, id uint, req *UpdateAgentRequest) (*models.Agent, error) {
	var agent models.Agent
	if err := database.DB.First(&agent, id).Error; err != nil {
		return nil, fmt.Errorf("agent not found: %w", err)
	}

	updateData := map[string]interface{}{
		"updated_by": req.UpdatedBy,
		"updated_at": time.Now(),
	}

	if req.Name != "" {
		updateData["name"] = req.Name
	}
	if req.Description != "" {
		updateData["description"] = req.Description
	}
	if req.Status != "" {
		updateData["status"] = req.Status
	}
	if req.Config != "" {
		updateData["config"] = req.Config
	}

	if err := database.DB.Model(&agent).Updates(updateData).Error; err != nil {
		return nil, fmt.Errorf("failed to update agent: %w", err)
	}

	return &agent, nil
}

// DeleteAgent 删除代理
func (s *AgentService) DeleteAgent(ctx context.Context, id uint) error {
	result := database.DB.Delete(&models.Agent{}, id)
	if result.Error != nil {
		return fmt.Errorf("failed to delete agent: %w", result.Error)
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("agent not found")
	}
	return nil
}

// ExecuteAgent 执行代理
func (s *AgentService) ExecuteAgent(ctx context.Context, agentID uint, req *ExecuteAgentRequest) (*models.Execution, error) {
	// 获取代理信息
	var agent models.Agent
	if err := database.DB.First(&agent, agentID).Error; err != nil {
		return nil, fmt.Errorf("agent not found: %w", err)
	}

	// 创建执行记录
	execution := &models.Execution{
		AgentID:     agentID,
		ExecutionID: uuid.New().String(),
		Input:       req.Input,
		Status:      "running",
		StartedAt:   &[]time.Time{time.Now()}[0],
	}

	if err := database.DB.Create(execution).Error; err != nil {
		return nil, fmt.Errorf("failed to create execution: %w", err)
	}

	// 异步执行代理任务
	go s.executeAgentTask(ctx, execution, &agent, req)

	return execution, nil
}

// executeAgentTask 执行代理任务（异步）
func (s *AgentService) executeAgentTask(ctx context.Context, execution *models.Execution, agent *models.Agent, req *ExecuteAgentRequest) {
	defer func() {
		if r := recover(); r != nil {
			logger.Logger.Error("Agent execution panicked",
				zap.Any("panic", r),
				zap.String("execution_id", execution.ExecutionID))

			s.updateExecutionStatus(execution.ID, "failed", "", fmt.Sprintf("Execution panicked: %v", r))
		}
	}()

	startTime := time.Now()

	// 这里实现具体的代理执行逻辑
	// 目前是模拟执行
	time.Sleep(2 * time.Second)

	// 模拟输出
	output := map[string]interface{}{
		"result":     "Task completed successfully",
		"timestamp":  time.Now(),
		"agent_type": agent.Type,
	}

	outputJSON, _ := json.Marshal(output)
	duration := time.Since(startTime).Milliseconds()

	s.updateExecutionStatus(execution.ID, "completed", string(outputJSON), "")
	s.updateExecutionDuration(execution.ID, duration)
}

// updateExecutionStatus 更新执行状态
func (s *AgentService) updateExecutionStatus(executionID uint, status, output, errorMsg string) {
	updateData := map[string]interface{}{
		"status":       status,
		"completed_at": time.Now(),
		"updated_at":   time.Now(),
	}

	if output != "" {
		updateData["output"] = output
	}
	if errorMsg != "" {
		updateData["error"] = errorMsg
	}

	database.DB.Model(&models.Execution{}).Where("id = ?", executionID).Updates(updateData)
}

// updateExecutionDuration 更新执行时长
func (s *AgentService) updateExecutionDuration(executionID uint, duration int64) {
	database.DB.Model(&models.Execution{}).Where("id = ?", executionID).Update("duration", duration)
}
